﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameViewer.Core.Viewers;
using GameViewer.Ogre;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace GameViewer.Core.Viewers
{
    public class OgreMeshViewer : MeshViewer
    {
        OgreMesh mMesh;
        BasicEffect mBasicEffect;
        VertexDeclaration mVertexDeclaration;

        public override void View(GameViewer.Core.Archives.FileInfo file)
        {
            try
            {
                mMesh = OgreMeshManager.Instance.Load(file);                
            }
            catch(Exception ex)
            {
                LogManager.Instance.LogMessage(ex.ToString(), LogMessageLevel.LML_CRITICAL, true);                
                return;
            }
            try
            {
                //tmp
                //解析Material
                foreach (OgreSubMesh subMesh in mMesh.SubMeshes)
                {
                    string materialName = subMesh.MaterialName;
                    OgreMaterial material = OgreMaterialManager.Instance.GetMaterial(materialName);
                    string textureName = material.Techniques[0].Passes[0].TextureUnitStates[0].TextureName;
                    if (mBasicEffect != null)
                    {
                        List<GameViewer.Core.Archives.FileInfo> files = file.Archive.FindFileInfo(textureName);
                        if (files.Count > 0)
                        {
                            Texture2D texture = Texture2D.FromFile(mDevice, files[0].Archive.Open(files[0].FileName));
                            mBasicEffect.Texture = texture;
                        }
                    }
                }
            }
            catch
            { }

            base.View(file);
        }

        protected override void Initialize()
        {
            base.Initialize();
            mBasicEffect = new BasicEffect(mDevice, null);
            mBasicEffect.TextureEnabled = true;
            mBasicEffect.EnableDefaultLighting();
            mBasicEffect.World = Matrix.Identity;
            mBasicEffect.View = mCameraViewMatrix;
            mBasicEffect.Projection = mCameraProjectionMatrix;
            //mVertexDeclaration = new VertexDeclaration(mDevice, mMesh.SubMeshes[0].VertexData.VertexElements.ToArray());
            mVertexDeclaration = new VertexDeclaration(mDevice, VertexPositionNormalTexture.VertexElements);
        }

        protected override void DrawModel()
        {
            base.DrawModel();

            mDevice.VertexDeclaration = mVertexDeclaration;
            mDevice.RenderState.CullMode = CullMode.None;
            mBasicEffect.Begin();
            mBasicEffect.World = mWorld;
            mBasicEffect.View = mCameraViewMatrix;
            mBasicEffect.Projection = mCameraProjectionMatrix;
            foreach (OgreSubMesh subMesh in mMesh.SubMeshes)
            {
                foreach (EffectPass pass in mBasicEffect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    if (subMesh.VertexData.VertexCount == 0)
                        continue;
                    mDevice.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(
                               Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList,
                               subMesh.VertexData.VertexList.ToArray(),
                               0,   // vertex buffer offset to add to each element of the index buffer
                               subMesh.VertexData.VertexList.Count,   // number of vertices to draw
                               subMesh.IndicieList.ToArray(),
                               0,   // first index element to read
                               subMesh.IndicieList.Count / 3    // number of primitives to draw
                           );
                    pass.End();
                }
            }
            mBasicEffect.End();
        }
    }
}
